package member.api;

import member.api.vo.AddressVo;
import member.model.common.Address;
import member.model.common.IpAddress;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * Created by Liang Wenxu on 2016/11/22.
 */
public interface AddressCommonApi {
    IpAddress findByIp(Long ipL);

    Address findAreaByIp(Long ipL, int areaLevelProvince);

    public static enum AddressLevel {
        COUNTRY(0), PROVINCE(1), CITY(2), AREA(3), TOWN(4);

        private final Integer value;

        // 构造器默认也只能是private, 从而保证构造函数只能在内部使用
        AddressLevel(Integer value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        // 普通方法
        public static AddressLevel getLevel(int levelCode) {
            for (AddressLevel c : AddressLevel.values()) {
                if (c.value == levelCode) {
                    return c;
                }
            }
            return null;
        }


        @Override
        public String toString() {
            return String.valueOf(this.getValue());
        }
    };


    /**
     * ID获取
     * @param id
     * @return
     */
    public Address findById(String id);

    /**
     * ID获取Vo
     * @param id
     * @return
     */
    public AddressVo findVoById(String id);

    /**
     * 获取地区列表
     * @param level 地区层级
     * @param parentId 父级ID，当为null时，列出该层级下所有数据
     * @param withChildren 是否包括子节点
     * @return
     */
    public List<Address> addressList(AddressLevel level, String parentId, Boolean withChildren);

    /**
     * 获取地区列表（列出给出层级下所有数据）
     * @param level 地区层级
     * @param withChildren 是否包括子节点
     * @return
     */
    public List<Address> addressList(AddressLevel level, Boolean withChildren);

    /**
     * 获取地区列表（转换成VO类）
     * @param level 地区层级
     * @param parentId 父级ID，当为null时，列出该层级下所有数据
     * @param withChildren 是否包括子节点
     * @return
     */
    public List<AddressVo> addressVoList(AddressLevel level, String parentId, Boolean withChildren);

    /**
     * 获取父级为parentId的首个地区
     * @param parentId
     * @param withChildren
     * @return
     */
    public Address findFirstChild(String parentId, Boolean withChildren);

    /**
     * 拼音首字母查找
     * @param firstChar 拼音首字母
     * @param level 地区层级，如不为null，则在指定层级下查找
     * @param withChildren 是否包括子节点
     * @return
     */
    public List<Address> findByFirstChar(String firstChar, AddressLevel level, Boolean withChildren);

    /**
     * 拼音查找
     * @param pingYing 拼音
     * @param level 地区层级，如不为null，则在指定层级下查找
     * @param withChildren 是否包括子节点
     * @return
     */
    public List<Address> findByPingYin(String pingYing, AddressLevel level, Boolean withChildren);

    /**
     * 按简拼查找
     * @param jp 地区简拼，如SH、SZ等
     * @param level 地区层级，如不为null，则在指定层级下查找
     * @param withChildren 是否包括子节点
     * @return
     */
    public List<Address> findByJianPing(String jp, AddressLevel level, Boolean withChildren);

    /**
     * 经纬度查找地区
     * @param level 地区层级
     * @param lng 经度
     * @param lat 纬度
     * @param lngRange 经度搜索精度，如传1，则查找 [lng - 1, lng + 1]范围内的所有数据
     * @param latRange 纬度搜索精度，如传1，则查找 [lat - 1, lat + 1]范围内的所有数据
     * @param withChildren 是否包括子节点
     * @return
     */
    public List<Address> findByCoordinates(String level, Float lng, Float lat, Float lngRange, Float latRange, Boolean withChildren);

    /**
     * 获取地区对应的层级节点列表
     * @param areaCode
     * @return
     */
    public Map<Integer, String> areaCodeNodeList(String areaCode);

    /**
     * 获取地区对应的层级节点列表
     * @param areaCode
     * @return
     */
    public Map<Integer, Address> areaNodeList(String areaCode);


    /**
     * 计算地区子节点数量
     * @param areaCode
     * @return
     */
    public Long childrenCounts(String areaCode);

    /**
     * 计算地区子节点数量
     * @param address
     * @return
     */
    public Long childrenCounts(Address address);

    public Address findByCityCode(String cityCode);

    public Map getAddressIdSByParams(HttpServletRequest request, HttpServletResponse response,String proviceId);

    public void setAddressIdSByParams(HttpServletRequest request, HttpServletResponse response,String areaId);


    public Map getIpAddressIds(HttpServletRequest request,HttpServletResponse response);

    public Map<String, Map<String, String>> transAreaCode(List<String> code);

    public String toString();
}
